#include "ibp_util.h"

void LocateIndexSpaceAddress( void *base , struct IndexSpaceAttaching **pp_index_space_attaching )
{
	(*pp_index_space_attaching) = (struct IndexSpaceAttaching *)base ;
	
	return;
}

void LocateConfigSpaceAddress( void *base , struct ConfigSpaceAttaching **pp_config_space_attaching , struct ConfigSpaceAddresses *p_config_space_adresses )
{
	(*pp_config_space_attaching) = (struct ConfigSpaceAttaching *)base ;
	
	p_config_space_adresses->nodes_hash_base = (struct NodeSpaceUnit *)( (char*)base + sizeof(struct ConfigSpaceAttaching) ) ;
	p_config_space_adresses->last_node_unit = p_config_space_adresses->nodes_hash_base + ((*pp_config_space_attaching)->nodes_hash_size-1) ;
	p_config_space_adresses->hosts_array_base = (struct HostSpaceUnit *)( (char*)(p_config_space_adresses->nodes_hash_base) + ((*pp_config_space_attaching)->nodes_hash_size*sizeof(struct NodeSpaceUnit)) ) ;
	p_config_space_adresses->apps_hash_base = (struct AppSpaceUnit *)( (char*)(p_config_space_adresses->hosts_array_base) + ((*pp_config_space_attaching)->hosts_array_size*sizeof(struct HostSpaceUnit)) ) ;
	p_config_space_adresses->last_app_unit = p_config_space_adresses->apps_hash_base + ((*pp_config_space_attaching)->apps_hash_size-1) ;
	
	return;
}

struct NodeSpaceUnit *TravelNodes( struct ConfigSpaceAddresses *p_config_space_addresses , struct NodeSpaceUnit *p_node_unit )
{
	int		offset ;
	
	if( p_node_unit == NULL )
		offset = 0  ;
	else
		offset = p_node_unit - p_config_space_addresses->nodes_hash_base + 1 ;
	
	for( p_node_unit = p_config_space_addresses->nodes_hash_base + offset ; p_node_unit <= p_config_space_addresses->last_node_unit ; p_node_unit++ )
	{
		if( p_node_unit->node[0] )
			return p_node_unit;
	}
	
	return NULL;
}

struct NodeSpaceUnit *QueryNode( struct ConfigSpaceAttaching *p_config_space_attaching , struct ConfigSpaceAddresses *p_config_space_addresses , char *node )
{
	unsigned long		hash_val ;
	struct NodeSpaceUnit	*p_node_unit = NULL ;
	int			j ;
	
	hash_val = CalcHash(node) % (p_config_space_attaching->nodes_hash_size) ;
	p_node_unit = p_config_space_addresses->nodes_hash_base + hash_val ;
	for( j = 0 ; j < p_config_space_attaching->nodes_hash_size ; j++ , p_node_unit++ )
	{
		if( p_node_unit > p_config_space_addresses->last_node_unit )
			p_node_unit = p_config_space_addresses->nodes_hash_base ;
		
		if( STRCMP( p_node_unit->node , == , node ) )
		{
			return p_node_unit;
		}
	}
	
	return NULL;
}

char *GetNodePtr( struct NodeSpaceUnit *p_node_unit )
{
	return p_node_unit->node;
}

char GetNodeInvalid( struct NodeSpaceUnit *p_node_unit )
{
	return p_node_unit->invalid;
}

int GetNodeHostCount( struct NodeSpaceUnit *p_node_unit )
{
	return p_node_unit->host_count;
}

char *GetNodeKey( struct NodeSpaceUnit *p_node_unit , int *p_key_len )
{
	if( p_key_len )
		(*p_key_len) = p_node_unit->key_len ;
	return p_node_unit->key;
}

struct HostSpaceUnit *TravelNodeHosts( struct ConfigSpaceAddresses *p_config_space_addresses , struct NodeSpaceUnit *p_node_unit , struct HostSpaceUnit *p_host_unit )
{
	int		offset ;
	
	if( p_host_unit == NULL )
		offset = p_node_unit->host_space_base_offset  ;
	else
		offset = p_host_unit - p_config_space_addresses->hosts_array_base + 1 ;
	
	if( offset - p_node_unit->host_space_base_offset >= p_node_unit->host_count )
		return NULL;
	
	return p_config_space_addresses->hosts_array_base+offset;
}

struct HostSpaceUnit *QueryNodeHost( struct ConfigSpaceAddresses *p_config_space_addresses , struct NodeSpaceUnit *p_node_unit , char *ip , int port )
{
	int			offset , overflow_offset ;
	struct HostSpaceUnit	*p_host_unit = NULL ;
	
	for( offset = p_node_unit->host_space_base_offset , overflow_offset = p_node_unit->host_space_base_offset + p_node_unit->host_count , p_host_unit = p_config_space_addresses->hosts_array_base + p_node_unit->host_space_base_offset ; offset < overflow_offset ; offset++ , p_host_unit++ )
	{
		if( STRCMP( p_host_unit->ip , == , ip ) && p_host_unit->port == port )
			return p_host_unit;
	}
	
	return NULL;
}

char *GetHostIpPtr( struct HostSpaceUnit *p_host_unit )
{
	return p_host_unit->ip;
}

int GetHostPort( struct HostSpaceUnit *p_host_unit )
{
	return p_host_unit->port;
}

int GetHostLoad( struct HostSpaceUnit *p_host_unit )
{
	return p_host_unit->load;
}

#if 0
char GetHostInvalid( struct HostSpaceUnit *p_host_unit )
{
	return p_host_unit->invalid;
}
#endif

struct AppSpaceUnit *TravelApps( struct ConfigSpaceAddresses *p_config_space_addresses , struct AppSpaceUnit *p_app_unit )
{
	int		offset ;
	
	if( p_app_unit == NULL )
		offset = 0  ;
	else
		offset = p_app_unit - p_config_space_addresses->apps_hash_base + 1 ;
	
	for( p_app_unit = p_config_space_addresses->apps_hash_base + offset ; p_app_unit <= p_config_space_addresses->last_app_unit ; p_app_unit++ )
	{
		if( p_app_unit->app[0] )
			return p_app_unit;
	}
	
	return NULL;
}

struct AppSpaceUnit *QueryApp( struct ConfigSpaceAttaching *p_config_space_attaching , struct ConfigSpaceAddresses *p_config_space_addresses , char *app )
{
	unsigned long		hash_val ;
	struct AppSpaceUnit	*p_app_unit = NULL ;
	int			j ;
	
	hash_val = CalcHash(app) % (p_config_space_attaching->apps_hash_size) ;
	p_app_unit = p_config_space_addresses->apps_hash_base + hash_val ;
	for( j = 0 ; j < p_config_space_attaching->apps_hash_size ; j++ , p_app_unit++ )
	{
		if( p_app_unit > p_config_space_addresses->last_app_unit )
			p_app_unit = p_config_space_addresses->apps_hash_base ;
		
		if( STRCMP( p_app_unit->app , == , app ) )
		{
			return p_app_unit;
		}
	}
	
	return NULL;
}

char *GetAppPtr( struct AppSpaceUnit *p_app_unit )
{
	return p_app_unit->app;
}

char *GetAppDescPtr( struct AppSpaceUnit *p_app_unit )
{
	return p_app_unit->desc;
}

char *GetAppBinPtr( struct AppSpaceUnit *p_app_unit )
{
	return p_app_unit->bin;
}

int GetAppTimeout( struct AppSpaceUnit *p_app_unit )
{
	return p_app_unit->timeout;
}

int GetAppTimeout2( struct AppSpaceUnit *p_app_unit )
{
	return p_app_unit->timeout2;
}

